#pragma once
//============================================================================
// Copyright (C) 2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include <string>
#include <vector>
#include "VxInetAddress.h"
#include <VxUtilLib/VxSktDefs.h>

#ifdef WIN_PLATFORM
	#include "Winsock2.h"
	#include <Ws2tcpip.h>  
	#define EINPROGRESS	WSAEWOULDBLOCK 
#endif // WIN_PLATFORM

#define SKT_CONNECT_TIMEOUT 5000
#define SKT_SEND_TIMEOUT 3000
#define SKT_RECEIVE_TIMEOUT 3000

// error codes
#define VX_NO_HOST_IPS_FOUND	-1
#define VX_INVALID_SOCK_ADDRESS -2

#define VX_MAX_HOST_IPS 10 //maximum host ips returned by


//! initialize sockets
RCODE			VxSocketsStartup( void );

void			VxFlushThenCloseSkt( SOCKET oSocket );
void			VxCloseSktNow( SOCKET oSocket );
void            VxCloseSkt( SOCKET oSocket );

bool            VxBindSkt( SOCKET oSocket, struct sockaddr_storage * poAddr );
bool            VxBindSkt( SOCKET oSocket, VxInetAddress & oLclAddr, U16 u16Port );

socklen_t       VxGetSktAddressLength( struct sockaddr_storage * poAddr );

void            VxSetSktAddressPort( struct sockaddr_storage * poAddr, U16 u16Port );

bool            VxTestConnectionOnSpecificLclAddress(  VxInetAddress &oLclAddr );

bool            VxResolveUrl( const char * pUrl, U16 u16Port, VxInetAddress& oRetAddr );

char *			VxIpToString( U32 u32IpAddr );

//! if new connection refresh default ip(s)
void			VxRefreshDefaultIps( void );

bool			VxCanConnectUsingIPv6( void );

//std::vector<VxInetAddress>& VxGetLocalIps( void );
void			VxGetLocalIps(	std::vector<VxInetAddress>& aRetIpAddress );

void			VxSetSelectedLocalIp( VxInetAddress& oIpAddr );
VxInetAddress	VxGetSelectedLocalIp( void );
VxInetAddress	VxGetMyGlobalIPv6Address( void );
VxInetAddress	VxGetDefaultIPv4Address( void );
VxInetAddress	VxGetDefaultIPv6Address( void );

//! return true if ip is in list of local ips
bool			VxLocalIpExists(  std::string& strIpAddress );

//! return true if port is already in use on this local ip address
bool			VxIsIpPortInUse(  U16 u16Port, const char * pLocalIp = NULL );

SOCKET			VxConnectTo( VxInetAddress& oLclIp, VxInetAddress& oRmtIp, U16 u16Port, int iTimeoutMs = SKT_CONNECT_TIMEOUT );

RCODE			VxSendSktData(	SOCKET&			oSkt,
								const char *	pData,					// data to send
								int				iDataLen,				// length of data
								int				iTimeoutSeconds = SKT_SEND_TIMEOUT );		// seconds before send attempt times out

//! receive data.. if timeout is set then will keep trying till buffer is full or error or timeout expires
RCODE			VxRecieveSktData(	SOCKET&			oSkt,
									char *			pRetBuf,				// buffer to receive data into
									int				iBufLenIn,				// length of buffer
									int *			iRetBytesRecieved,		// number of bytes actually received
									int				iTimeoutMilliSeconds = SKT_RECEIVE_TIMEOUT,	// milliseconds before receive attempt times out ( 0 = dont wait )
									BOOL			bAbortIfCrLfCrLf = false,		// if true then abort receive when \r\n\r\n is received
									BOOL *			pbRetGotCrLfCrLf  = NULL );		// if received \r\n\r\n set to true

RCODE			VxSetSktBlocking( SOCKET& oSkt, bool bBlock );

//! split host name from website file path
bool			VxSplitHostAndFile(	const char * pFullUrl,			// full url.. example http://www.mysite.com/index.html or www.mysite.com/images/me.jpg
									std::string& strRetHost,		// return host name.. example http://www.mysite.com/index.htm returns www.mysite.com
									std::string& strRetFileName,	// return file name.. images/me.jpg
									U16& u16RetPort );				// return port if specified else return 80 as default				

void VxFillHints( struct addrinfo& oHints, bool bUdpSkt = false);

//============================================================================
void VxIP_ntop( int family, void * pvBinary, char * pBuf, int iBufLen, bool isHostOrder = true );
void VxIPv4_ntop( void * pvBinary, char * pBuf, int iBufLen, bool isHostOrder = true );
void VxIPv6_ntop( void * pvBinary, char * pBuf, int iBufLen );
void VxIPv4_pton( const char * pIpString,  void * pvBinary, bool wantHostOrder = true );
void VxIPv6_pton( const char * pIpString,  void * pvBinary );

//! describe skt errors
const char * DescribeSktErr( int iErr );

bool			VxIsIPv6Address( const char *addr );
int				VxGetIPv6ScopeID( const char *addr );
const char *	VxStripIPv6ScopeID( const char *addr, std::string &buf );


